// poj3522
// 题意：给定一个图，求生成树使得最大边减最小边的值最小，输出这个值，如果
//       没有生成树，输出-1。
//
// 题解：其实差不多O(n^4)能过，枚举最小边，然后求对应最小生成树，然后不断
//       更新答案。
//       然后知道一个性质，最小生成树上的边的权值，在不同的最小生成树上也是
//       一一映射的。
//
// 统计：719ms, 16min, 1a
//
// run: $exec < input
#include <cstdio>
#include <algorithm>

struct edge { int from, to, cost; };
bool operator<(edge const & a, edge const & b) { return a.cost < b.cost; }

int const inf = 1 << 30;
int const maxn = 107;
int const maxm = maxn * maxn;
edge edges[maxm];
int parent[maxn];
int n, m;

int get_parent(int u)
{
	return parent[u] == u ? u : (parent[u] = get_parent(parent[u]));
}

void set_union(int u, int v)
{
	int tu = get_parent(u);
	int tv = get_parent(v);
	if (tu != tv) parent[tu] = tv;
}

int kruskal(int start)
{
	for (int i = 1; i <= n; i++)
		parent[i] = i;

	int min_edge = edges[start].cost, max_edge = 0, count = 0;
	for (int i = start; i < m; i++) {
		int u = edges[i].from, v = edges[i].to, c = edges[i].cost;
		if (get_parent(u) == get_parent(v)) continue;
		set_union(u, v);
		max_edge = c;
		count++;
	}
	if (count != n - 1) return -1;
	return max_edge - min_edge;
}

int main()
{
	while (std::scanf("%d %d", &n, &m) && (n || m)) {
		for (int i = 0; i < m; i++) std::scanf("%d %d %d", &edges[i].from, &edges[i].to, &edges[i].cost);
		std::sort(edges, edges + m);

		int ans = inf;
		bool unconnected = true;
		for (int i = 0; i < m; i++) {
			int tmp = kruskal(i);
			if (tmp == -1) continue;
			ans = std::min(ans, tmp);
			unconnected = false;
		}

		if (unconnected) std::printf("-1\n");
		else std::printf("%d\n", ans);
	}
}

